#pragma once

#include "file.h"
#include "fstream.h"
#include "socket.h"
#include "task.h"
#include <cstdint>
#include <unordered_map>

namespace cobt {
class HttpRequest {
public:
  HttpRequest();
  HttpRequest(std::string &&path, std::string &&method,
              std::unordered_map<std::string, std::string> &&headers,
              std::string &&body);
  Task<bool> write_into(FileStream &fs);

private:
  std::string m_body;
  std::unordered_map<std::string, std::string> m_headers;
  std::string m_method;
  std::string m_path;
};

class HttpResponse {
public:
  friend class WebSocket;
  HttpResponse() = default;

  HttpResponse(HttpResponse &&that) = default;
  Task<bool> read_from(FileStream &fs);
  std::string get_body() const;

private:
  int m_status;
  std::unordered_map<std::string, std::string> m_headers;
  std::string m_body;
};
struct HttpPromise : cobt::Promise<std::optional<HttpResponse>> {
  auto get_return_object() {
    return std::coroutine_handle<HttpPromise>::from_promise(*this);
  }
  UnInit<cobt::FileHandle> m_conn;
};
class HttpClient {
public:
  HttpClient(const std::string &host, uint16_t port);
  Task<std::optional<HttpResponse>, HttpPromise> get(const std::string &path);

private:
  std::string m_host;
  uint16_t m_port;
  FileHandle m_conn;
};
} // namespace cobt
